//
// Created by zken on 2024/12/2.
//

#include "attrFormatTree.h"


AstTreeNode *attrFormatTree::doAttribute(int productionId, const vector<AnalyseValue> &values) {
    AstTreeNode *rTreeNode = nullptr; // 返回值如果是null，肯定是出现了错误
    cout << "attrFormatTree: execute" << productionId << endl;
    production p_t = productionUtil1->productions[productionId];
    // 处理空,设置配置文件中的-1为标记空
    ProductionConfig pc_t = pConfig[productionId];
    AstTreeNode *currNode = nullptr;

    if (pc_t.left == "1"
        || pc_t.right[0] == "-1") {
        AstTreeNode *nNode = new AstTreeNode();
        nNode->value = p_t.left + ":";
        currNode = nNode;
    }
    // 找到作为根的leaf
    // 先处理左部

    for (int i = 0; i < pc_t.right.size(); i++) {
        string state = pc_t.right[i];
        if (state == "4") {
            currNode = values.at(i).ptr2;
            break;
        } else if (state == "2") {
            currNode = makeLeaf(values.at(i));
            break;
        }
    }

    int startIndex = 0;
    if (currNode == nullptr) {
        cout << "指定了右部的最左侧为根" << endl;
        if (values.at(0).ptr2 == nullptr) {
            cout << "配置文件错误，无法识别使用的父亲节点" << endl;
            // 抛出错误
            return nullptr;
        }
        currNode = values.at(0).ptr2;
        startIndex += 1;
    }
    // 对右部处理，如果使用了：指定了右部的最左侧为根，则越过i=0
    for (; startIndex < pc_t.right.size(); startIndex++) {
        string state = pc_t.right[startIndex];
        if (state == "0") {
            if (productionUtil1->isVT(values.at(startIndex).tokenType)) {
                currNode->children.push_back(makeLeaf(values.at(startIndex)));
            } else {
                currNode->children.push_back(values.at(startIndex).ptr2);
            }
        } else if (state == "1") {
        } else if (state == "3") {
            currNode->children.push_back(makeLeaf(values.at(startIndex)));
        }
    }
    rTreeNode = currNode;


    if (rTreeNode == nullptr) {
        // 抛出错误
    }
    return rTreeNode;
}

FourthTuple attrFormatTree::doAttributeFac(int productionId, const vector<AnalyseValue> &values) {
    production p_t = productionUtil1->productions[productionId];
    // 处理空,设置配置文件中的-1为标记空
    ProductionConfig pc_t = pConfig[productionId];
    // 产生四元组的语义动作
    string facWork = pc_t.facWork;
    stringstream ss(facWork);
    // 执行的四元组代码，如gen
    string func;
    ss >> func;
    FourthTuple tuple;
    tuple.setOp("-1");// -1标记这个是个错误项，如果被push_back了就是出错
    if (func.empty()) {
        return tuple;
    }
    // 如果执行的代码类型是gen
    if (func == "gen") {
        // 四元组的四个内容
        string op;
        ss >> op;
        string arg1;
        ss >> arg1;
        string arg2;
        ss >> arg2;
        string tag;
        ss >> tag;

        // 判断是否是数字，如果是数字，则使用values对应位置进行添加，如果不是，直接添加字符串
        if (util::isNumber(op)) {
            int i = stoi(op);
            if (!values.at(i).ptr2->placeTag.empty()) {
                op = values.at(i).ptr2->placeTag;
            } else {
                op = values.at(i).ptr2->value;
            }
        }
        if (util::isNumber(arg1)) {
            int i = stoi(arg1);
            if (!values.at(i).ptr2->placeTag.empty()) {
                arg1 = values.at(i).ptr2->placeTag;
            } else {
                arg1 = values.at(i).ptr2->value;
            }
        }
        if (util::isNumber(arg2)) {
            int i = stoi(arg2);
            if (!values.at(i).ptr2->placeTag.empty()) {
                arg2 = values.at(i).ptr2->placeTag;
            } else {
                arg2 = values.at(i).ptr2->value;
            }
        }
        if (util::isNumber(tag)) {
            int i = stoi(tag);
            if (!values.at(i).ptr2->placeTag.empty()) {
                tag = values.at(i).ptr2->placeTag;
            } else {
                tag = values.at(i).ptr2->value;
            }
        }
        tuple = tupleList.gen(op, arg1, arg2, tag);
    }
    // 如果执行的代码类型是record
    if(func=="record")
    {
        tuple.setOp(func);
        tuple.setTag(tupleList.getNextLineId());
    }

    return tuple;
}


void attrFormatTree::readConfig(const string &filePath) {
    // 加入扩展文法-加入一个占位对象
    ProductionConfig fix;
    fix.left = "ext";
    pConfig.push_back(fix);
    vector<string> lines = readUtil::readFile(filePath);

    for (string line: lines) {
        if (line.empty()) {
            break;
        }
        readConfigLine(line);
    }
}

void attrFormatTree::readConfigLine(const string &line) {

    //先获取语义动作-构建四元组
    string facWork = util::getSubstringAfterChar('\\', line);
    string newLine = util::getSubstringBeforeChar('\\', line);
    // 开始获取当行的文法
    stringstream ss(newLine);
    // 整体的左部
    string left;
    ss >> left;
    left = readConfigLineGetAttr(left);
    string arrow;
    ss >> arrow;
    vector<string> parts;
    // 公共的左部

    while (!ss.eof()) {
        string temp;
        ss >> temp;
        if (temp.empty()) {
            continue;
        }
        if (temp == "|") {
            pConfig.emplace_back(left, parts, facWork);
            parts.clear();
            continue;
        } else {
            // 累计右部内容
            parts.push_back(readConfigLineGetAttr(temp));
        }
    }
    // 补全最后一次读入
    pConfig.emplace_back(left, parts, facWork);
}

void attrFormatTree::showPConfig() {
    for (ProductionConfig p: pConfig) {
        cout << p.left << " " << "->" << p.getRightString() << endl;
    }
}

string attrFormatTree::readConfigLineGetAttr(const string &s) {
    string res = s;
    if (s.find(':') != string::npos) {
        int idx = s.find(':');
        int len = s.size() - idx;
        res = s.substr(idx + 1, len);
    } else {
        res = "0";
    }
    return res;
}

AstTreeNode *attrFormatTree::makeLeaf(const AnalyseValue &value) {
    AstTreeNode *newLeaf = new AstTreeNode();
    newLeaf->value = value.tokenContent;
//    newLeaf->value = value.tokenType + ":" + value.tokenContent;
    return newLeaf;
}

void attrFormatTree::showAstTree() {
    if (this->root == nullptr) {
        cout << "AST树节点为空" << endl;
        return;
    }
    try {
        showTreeNodesSupport(this->root, 0);
    } catch (...) {
        throw AST_TREE_ERROR();
    }
}

void attrFormatTree::showTreeNodesSupport(AstTreeNode *root, int depth) {
    cout << string(depth, '.') << root->value << endl;
    for (int i = 0; i < root->children.size(); i++) {
        AstTreeNode *childNode = root->children[i];
        if (childNode == nullptr) {
            cout << root->value << "的儿子下存在空儿子" << endl;
        }
        showTreeNodesSupport(childNode, depth + 1);
    }
}

void attrFormatTree::setProductionUtil1(ProductionUtil *productionUtil1) {
    attrFormatTree::productionUtil1 = productionUtil1;
}

const vector<ProductionConfig> &attrFormatTree::getPConfig() const {
    return pConfig;
}

AstTreeNode *attrFormatTree::getRoot() const {
    return root;
}

void attrFormatTree::showFac() {
    vector<FourthTuple> tList = tupleList.getList();
    for (int i = 0; i < tList.size(); i++) {
        FourthTuple t = tList[i];
        cout << t.getToString() << endl;
    }
}

void attrFormatTree::setTupleList(const FourthTupleList &tupleList) {
    attrFormatTree::tupleList = tupleList;
}
